package appVeterinaria.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import appVeterinaria.excepcion.DAOExcepcion;
import appVeterinaria.modelo.Cita;
import appVeterinaria.modelo.CitaServicio;
import appVeterinaria.modelo.Cliente;
import appVeterinaria.modelo.Factura;
import appVeterinaria.modelo.Paciente;
import appVeterinaria.modelo.Servicio;
import appVeterinaria.util.ConexionBD;

public class FacturaDAO extends BaseDAO {

	public Collection<Factura> buscarPorIdFactura(int idFactura)
			throws DAOExcepcion {
		String query = "select idFactura, fe_registro_Factura, montoTotal from factura where idFactura=?";
		Collection<Factura> lista = new ArrayList<Factura>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1,idFactura);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Factura vo = new Factura();

				vo.setIdFactura(rs.getInt("idFactura"));
				// vo.setObjCita(("citas_idCitas"));
				vo.setFechaRegistro(rs.getString("fe_registro_Factura"));
				vo.setMontoTotal(rs.getDouble("montototal"));
				lista.add(vo);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		// System.out.println(lista.size());
		return lista;
	}

	public Collection<Factura> buscarPorFecha(String fechaReg)
			throws DAOExcepcion {
		String query = "select idFactura, citas_idCitas,fe_registro_Factura,cantidad from factura where idFactura like ?";
		Collection<Factura> lista = new ArrayList<Factura>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, fechaReg);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Factura vo = new Factura();
				vo.setIdFactura(rs.getInt("idFactura"));
				// vo.setObjCita(("citas_idCitas"));
				vo.setFechaRegistro(rs.getString("fe_registro_Factura"));
				vo.setCantidad(rs.getInt("cantidad"));
				vo.setMontoTotal(rs.getDouble("montototal"));
				lista.add(vo);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		// System.out.println(lista.size());
		return lista;
	}

	public Factura insertar(Factura vo) throws DAOExcepcion {
		String query = "insert into factura(fe_registro_Factura, montoTotal) values (?,?)";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);

			stmt.setString(1, vo.getFechaRegistro());
			stmt.setDouble(2, vo.getMontoTotal());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}

			// Obtener el ultimo id
			int id = 0;
			query = "select last_insert_id()";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()) {
				id = rs.getInt(1);
			}
			vo.setIdFactura(id);

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public CitaServicio insertarCitasServicios(CitaServicio vo)
			throws DAOExcepcion {
		String query = "insert into citas_servicios(servicios_idServicio, cita_idCita, cantidad, costo, factura_idFactura) values (?,?,?,?,?)";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);

			stmt.setInt(1, vo.getObjServicio().getIdServicio());
			stmt.setInt(2, vo.getObjCita().getIdCita());
			stmt.setInt(3, vo.getCantidad());
			stmt.setDouble(4, vo.getCosto());
			stmt.setInt(5, vo.getObjFactura().getIdFactura());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public Factura obtener(int idFactura) throws DAOExcepcion {
		Factura vo = new Factura();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String query = "select idFactura, citas_idCitas,fe_registro_Factura,cantidad from factura where idFactura like ?";
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idFactura);
			rs = stmt.executeQuery();
			if (rs.next()) {
				vo.setIdFactura(rs.getInt("idFactura"));
				// vo.setObjCita(("citas_idCitas"));
				vo.setFechaRegistro(rs.getString("fe_registro_Factura"));
				vo.setCantidad(rs.getInt("cantidad"));
				vo.setMontoTotal(rs.getDouble("montototal"));

			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public void eliminar(int idFactura) throws DAOExcepcion {
		String query = "delete from factura WHERE idFactura=?";
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idFactura);
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo eliminar");
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	}

	public Factura actualizar(Factura vo) throws DAOExcepcion {
		String query = "update factura set idFactura=?,idCitas=?, idServicio=?, idDoctor=?, idPaciente=?, idCliente=?, cantidad=? where idFactura=?";
		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = ConexionBD.obtenerConexion();

			stmt = con.prepareStatement(query);

			stmt.setInt(1, vo.getIdFactura());
			// stmt.setString(2, vo.getObjCita());
			stmt.setString(3, vo.getFechaRegistro());
			stmt.setInt(4, vo.getCantidad());
			stmt.setDouble(8, vo.getMontoTotal());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo actualizar");
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public Collection<Factura> listar() throws DAOExcepcion {
		Collection<Factura> f = new ArrayList<Factura>();
		Collection<CitaServicio> cs = new ArrayList<CitaServicio>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select cli.idcliente, cli.nombres, cli.apellidos, direccion, p.idPaciente, p.nombre, c.idCita, idServicio, s.des_servicio, costo_servicio, f.idFactura, fe_registro_factura, cantidad, costo, montoTotal from cliente cli inner join paciente p on cli.idcliente=p.cliente_idcliente inner join cita c on c.paciente_idpaciente=p.idpaciente inner join citas_servicios cs on cs.cita_idcita=c.idcita inner join servicios s on s.idservicio=cs.servicios_idservicio inner join factura f on f.idfactura=cs.factura_idfactura group by idCliente";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Factura vo = new Factura();
				Cliente objCliente = new Cliente();
				Servicio objServicio = new Servicio();
				Paciente objPaciente = new Paciente();
				CitaServicio objCitaServicio = new CitaServicio();
				Cita objCita = new Cita();
				objCliente.setIdPersona(rs.getInt("cli.idcliente"));
				objCliente.setNombres(rs.getString("cli.nombres"));
				objCliente.setApellidos(rs.getString("cli.apellidos"));
				objCliente.setDireccion(rs.getString("direccion"));
				objPaciente.setIdPaciente(rs.getInt("p.idPaciente"));
				objPaciente.setNombre(rs.getString("p.nombre"));
				objPaciente.setObjCliente(objCliente);
				objCita.setIdCita(rs.getInt("c.idCita"));
				objCita.setObjPaciente(objPaciente);
				objServicio.setIdServicio(rs.getInt("idServicio"));
				objServicio.setDescripcion(rs.getString("s.des_servicio"));
				objServicio.setCosto(rs.getDouble("costo_servicio"));
				vo.setIdFactura(rs.getInt("f.idFactura"));
				vo.setFechaRegistro(rs.getString("fe_registro_Factura"));
				vo.setObjCita(objCita);
				objCitaServicio.setObjServicio(objServicio);
				objCitaServicio.setObjCita(objCita);
				objCitaServicio.setObjFactura(vo);
				objCitaServicio.setCantidad(rs.getInt("cantidad"));
				objCitaServicio.setCosto(rs.getDouble("costo"));
				vo.setMontoTotal(rs.getDouble("montoTotal"));
				cs.add(objCitaServicio);
				vo.setCitaservicio(cs);

				f.add(vo);
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return f;
	}

	public Collection<CitaServicio> detalleFactura(int idFactura)
			throws DAOExcepcion {

		Collection<CitaServicio> cs = new ArrayList<CitaServicio>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select servicios_idServicio, des_servicio, costo_servicio, cita_idCita, cantidad, costo from citas_servicios cs inner join servicios s on s.idservicio=cs.servicios_idservicio where factura_idFactura=?";
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idFactura);
			rs = stmt.executeQuery();

			while (rs.next()) {
				Factura objFactura = new Factura();
				objFactura.setIdFactura(idFactura);

				Servicio objServicio = new Servicio();
				objServicio.setIdServicio(rs.getInt("servicios_idServicio"));
				objServicio.setDescripcion(rs.getString("des_servicio"));
				objServicio.setCosto(rs.getInt("costo_servicio"));

				Cita objCita = new Cita();
				objCita.setIdCita(rs.getInt("cita_idCita"));

				CitaServicio vo = new CitaServicio();

				vo.setObjServicio(objServicio);
				vo.setObjCita(objCita);
				vo.setObjFactura(objFactura);
				vo.setCantidad(rs.getInt("cantidad"));
				vo.setCosto(rs.getInt("costo"));

				cs.add(vo);
				objFactura.setCitaservicio(cs);
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return cs;
	}

	public Collection<Servicio> listarServicio() throws DAOExcepcion {

		Collection<Servicio> s = new ArrayList<Servicio>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select idServicio, des_servicio, costo_servicio from servicios";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();

			while (rs.next()) {

				Servicio vo = new Servicio();

				vo.setIdServicio(rs.getInt("idServicio"));
				vo.setDescripcion(rs.getString("des_servicio"));
				vo.setCosto(rs.getInt("costo_servicio"));

				s.add(vo);

			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return s;
	}

	public Collection<Factura> listarFactura() throws DAOExcepcion {

		Collection<Factura> f = new ArrayList<Factura>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select idFactura, fe_registro_Factura, montoTotal from factura order by fe_registro_Factura DESC";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();

			while (rs.next()) {

				Factura vo = new Factura();

				vo.setIdFactura(rs.getInt("idFactura"));
				vo.setFechaRegistro(rs.getString("fe_registro_Factura"));
				vo.setMontoTotal(rs.getDouble("montoTotal"));

				f.add(vo);

			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return f;
	}
	
	public double obtenerCostoServicio(int idServicio) throws DAOExcepcion {

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		double costo = 0.0;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select idServicio, costo_servicio from servicios where idServicio=?";
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idServicio);
			rs = stmt.executeQuery();
			if (rs.next()) {

				Servicio vo = new Servicio();
				vo.setIdServicio(rs.getInt("idServicio"));
				vo.setCosto(rs.getDouble("costo_servicio"));

				costo = vo.getCosto();

			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return costo;
	}
	
	public int obtenerUltimoId() throws DAOExcepcion {

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		int idFactura=0;
		
		try {
			con = ConexionBD.obtenerConexion();
			String query = "Select idFactura from factura order by idFactura DESC LIMIT 1";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()) {
		    int id= rs.getInt("idFactura");
				idFactura=id;

			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return idFactura;
	}

}